package com.kp.ai.service;

import com.kp.ai.entity.CarBooking;
import com.kp.ai.entity.CarType;
import com.kp.ai.repository.CarBookingRepository;
import com.kp.ai.repository.CarTypeRepository;
import com.kp.ai.repository.CustomerRepository;
import com.kp.ai.service.function.CarBookingFunction;
import com.kp.ai.enums.BookingStatus;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Service
public class CarBookingService {

	private final CarBookingRepository carBookingRepository;
	private final CarTypeRepository carTypeRepository;
	private final CustomerRepository customerRepository;
	private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

	public CarBookingService(CarBookingRepository carBookingRepository, CarTypeRepository carTypeRepository, CustomerRepository customerRepository) {
		this.carBookingRepository = carBookingRepository;
		this.carTypeRepository = carTypeRepository;
		this.customerRepository = customerRepository;
		}

	// 获取所有车辆类型
	public List<CarType> getAllCarTypes() {
		return carTypeRepository.findAll();
	}

	// 分页获取出行订单
	public Page<CarBookingFunction.BookingDetails> getCarOrders(Pageable pageable) {
		return carBookingRepository.findAll(pageable)
			.map(this::toBookingDetails);
	}

	// 根据编号查询出行订单
	private CarBooking findBooking(String bookingNumber) {
		return carBookingRepository.findAll().stream()
			.filter(b -> b.getBookingNumber().equalsIgnoreCase(bookingNumber))
			.findFirst()
			.orElseThrow(() -> new IllegalArgumentException("CarBooking not found"));
	}

	// 查询订单详情
	public CarBookingFunction.BookingDetails getBookingDetails(String bookingNumber, String name) {
		var booking = findBooking(bookingNumber);
		return toBookingDetails(booking);
	}

	// 更改目的地
	@Transactional
	public void changeBooking(String bookingNumber, String name, String newDate, String from, String to, Long carTypeId) {
		var booking = findBooking(bookingNumber);
		booking.setBookingDate(LocalDate.parse(newDate, DATE_FORMATTER));
		booking.setFromLocation(from);
		booking.setToLocation(to);
		
		// 更新车辆类型
		if (carTypeId != null) {
			var carType = carTypeRepository.findById(carTypeId)
				.orElseThrow(() -> new IllegalArgumentException("Car type not found"));
			booking.setCarType(carType);
		}
		
		carBookingRepository.save(booking);
	}

	// 取消订单
	@Transactional
	public void cancelBooking(String bookingNumber) {
		var booking = findBooking(bookingNumber);
		if (booking.getBookingStatus().equals("CANCELLED")) {
			throw new IllegalArgumentException("Your order has been cancelled and cannot be operated");
		}
		if (booking.getBookingDate().isBefore(LocalDate.now())) {
			throw new IllegalArgumentException("CarBooking cannot be cancelled of the start date.");
		}
		booking.setBookingStatus("CANCELLED");
		carBookingRepository.save(booking);
	}

	@Transactional
	public void createBooking(String name, String date, String from, String to, Long carTypeId, String carTypeName, String phone) {
		// 加强对乘车人名字的验证
		if (name == null || name.trim().isEmpty()) {
			throw new IllegalArgumentException("乘车人姓名为必填项");
		}
		if (date == null || from == null || to == null) {
			throw new IllegalArgumentException("日期、出发地和目的地均为必填项");
		}
		CarType carType = null;
		if (carTypeId != null && carTypeRepository.existsById(carTypeId)) {
			carType = carTypeRepository.findById(carTypeId)
				.orElseThrow(() -> new IllegalArgumentException("车辆类型不存在"));
		} else if (carTypeName != null && !carTypeName.isEmpty()) {
			carType = carTypeRepository.findByTypeName(carTypeName)
				.orElseThrow(() -> new IllegalArgumentException("车型不存在"));
		} else {
			throw new IllegalArgumentException("车型信息缺失");
		}
		// 查找或创建客户
		com.kp.ai.entity.Customer customer = customerRepository.findByNameAndPhone(name, phone)
			.orElseGet(() -> {
				com.kp.ai.entity.Customer c = new com.kp.ai.entity.Customer();
				c.setName(name);
				c.setPhone(phone);
				return customerRepository.save(c);
			});
		String bookingNumber = "BK" + java.time.LocalDate.now().toString().replace("-","") + System.currentTimeMillis()%100000;
		CarBooking booking = new CarBooking();
		booking.setBookingNumber(bookingNumber);
		booking.setBookingDate(LocalDate.parse(date, DATE_FORMATTER));
		booking.setFromLocation(from);
		booking.setToLocation(to);
		booking.setCarType(carType);
		booking.setBookingStatus("CONFIRMED");
		booking.setCustomer(customer);
		carBookingRepository.save(booking);
	}

	private CarBookingFunction.BookingDetails toBookingDetails(CarBooking booking) {
		return new CarBookingFunction.BookingDetails(
				booking.getBookingNumber(),
				booking.getCustomer().getName(),
				booking.getBookingDate(),
				BookingStatus.valueOf(booking.getBookingStatus()),
				booking.getFromLocation(),
				booking.getToLocation(),
				booking.getCarType()
		);
	}
}
